﻿using LJ.DataAccess.Abstractions;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Linq.Expressions;

namespace LJ.DataAccess.EntityFrameworkCore.Internal;

public abstract class EFDataProviderBase : IDataProvider
{
    public ITransactionalProvider TransactionalProvider { get; } = null!;
    public DataAccessDbContext Context { get; } = null!;

    public EFDataProviderBase(ITransactionalProvider transactionalProvider)
    {
        TransactionalProvider = transactionalProvider;
        if (transactionalProvider is not EFTransactionalProviderBase transactionalProviderBase)
        {
            throw new AppException($"{GetType().FullName} ITransactionalProvider is not {nameof(EFTransactionalProviderBase)}");
        }

        Context = transactionalProviderBase.GetDbContext();
    }
}


public abstract class EFDataProviderBase<T>(ITransactionalProvider transactionalProvider) : EFDataProviderBase(transactionalProvider), IDataProvider<T>
    where T : class, IEntityObject
{
    public async Task AddAsync(T entityObject, CancellationToken cancellationToken = default)
    {
        await Context.Set<T>().AddAsync(entityObject, cancellationToken);
    }

    public Task DeleteAsync(T entityObject, CancellationToken cancellationToken = default)
    {
        cancellationToken.ThrowIfCancellationRequested();
        Context.Set<T>().Remove(entityObject);

        return Task.CompletedTask;
    }

    public Task UpdateAsync(T entityObject, CancellationToken cancellationToken = default)
    {
        cancellationToken.ThrowIfCancellationRequested();

        Context.Set<T>().Update(entityObject);

        return Task.CompletedTask;
    }

    public async Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
    {
        if (predicate != null)
        {
            return await Context.Set<T>().FirstOrDefaultAsync(predicate, cancellationToken);
        }
        return await Context.Set<T>().FirstOrDefaultAsync(cancellationToken);
    }
}
